#include "../kernel.h"

int
task_init(void)
{
	 int i;
	 for (i = 0; i != sysconf.lcpu_count; ++ i)
	 {
		  volatile struct taskstate_t *task = TASK(lcpus[i].apic_id);
		  lcpus[i].task = task;
		  
		  /* intialize the TSS and load it into lcpu register */
		  gdt[GD_TSS(i) >> 3] = SEG16(STS_T32A, (uint32_t)task,
								   sizeof(struct taskstate_t), 0x0);
		  gdt[GD_TSS(i) >> 3].s = 0;

		  memset((void *)task, 0, sizeof(struct taskstate_t));
     
		  // asm volatile("movw %%ss, %0 " : "=r"(task->ss0));
		  
		  task->ss0 = GD_KERN_DATA;
		  
		  task->cs = GD_KERN_TEXT | 3;
		  task->ss = task->ds = task->es = task->fs = task->gs = GD_KERN_DATA | 3;
		  task->esp0 = PROC_KSTACK_TOP(lcpus[i].idle_pid);
	 }
	 kprintf("BOOT APIC ID %d\n", lcpus[sysconf.lcpu_boot].apic_id);
	 asm volatile("ltr %%ax" :: "a" (GD_TSS(lcpus[sysconf.lcpu_boot].apic_id) | 3));
     return 0;
}

int
task_init_ap(void)
{
	 asm volatile("ltr %%ax" :: "a" (GD_TSS(cur_lcpu()) | 3));
}

uintptr_t
get_task_ksp(apic_id_t lcpu)
{
	 return lcpus[lcpu].task->esp0;
}

void
set_task_ksp(apic_id_t lcpu, uintptr_t ksp)
{
	 lcpus[lcpu].task->esp0 = ksp;
}

